import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;

public class Awara_OS_FCFS {

    public static int i;
    public double awara[];
    public double awara1[];
    public int process_number;//进程数量
    public double arrival_time[];//进程到达时间
    public double services_time[];//进程服务时间
    public double start_time[];//进程开始时间
    public double wait_time[];//进程等待时间
    public double completion_time[];//进程完成时间
    public double turn_around_time[];//周转时间
    public double turn_around_time_with_weight[];//带权周转时间


    private void Set_process_number(int process_nuber) {
        this.process_number = process_nuber;
        //设置进程数量
    }

    private double get_process_number() {
        return process_number;
        //获取进程数量
    }

    private void Set_arrival_time(int arrival_time[]) {
        for (i = 0; i < process_number; i++) {
            this.arrival_time[i] = arrival_time[i];
        }
        //设置进程到达时间
    }

    private double[] get__arrival_time() {

        for (i = 0; i < process_number; i++) {
            awara[i] = arrival_time[i];
        }
        return awara;
        //获取进程到达时间
    }

    private void Set_services_time(int services_time[]) {
        for (i = 0; i < process_number; i++) {
            this.services_time[i] = services_time[i];
        }
        //设置进程服务时间
    }

    private double[] get_services_time() {
        for (i = 0; i < process_number; i++) {
            awara1[i] = services_time[i];
        }
        return awara1;
        //获得进程服务时间
    }

    //FCFS算法实现
    //周转时间=完成时间-到达时间
    //带权周转时间=周转时间/运行时间
    //等待时间=周转时间-运行时间
    private void FCFS() {
        double average_turn_around_time=0;//平均周转时间
        double average_turn_around_time_with_weight=0;//平均带权周转时间
        double now=0;
        start_time[0] = arrival_time[0];
        now=arrival_time[0];
        completion_time[0] = arrival_time[0] + services_time[0];
        start_time[0] = arrival_time[0];
        turn_around_time[0] = completion_time[0] - arrival_time[0];
        turn_around_time_with_weight[0] = turn_around_time[0]
                / services_time[0];
        now=completion_time[0];
        //设置第一个到达的进程的开始时间==到达时间
        //完成时间==到达时间+服务时间
        //第一个进程没有等待时间
        //周转时间=完成时间-到达时间
        //带权周转时间=周转时间/运行时间

        for (i = 1; i < process_number; i++) {
            if(arrival_time[i]>now){
                start_time[i]=arrival_time[i];
                wait_time[i]=0;
                completion_time[i]=arrival_time[i] + services_time[i];
                now=completion_time[i];
            }
            else if(arrival_time[i]<=now){
                start_time[i] = completion_time[i - 1];
                wait_time[i] = start_time[i] - arrival_time[i];
                completion_time[i] = arrival_time[i] + services_time[i]
                        + wait_time[i];
                now=completion_time[i];
            }
            turn_around_time[i] = completion_time[i] - arrival_time[i];
            turn_around_time_with_weight[i] = turn_around_time[i]
                    / services_time[i];

        }
        //除第一个进程之外的所有进程开始时间为前一个进程的完成时间
        //等待时间为该进程的开始时间-到达时间
        //完成时间为该进程的到达时间+服务时间+等待时间
        //周转时间为该进程完成时间-到达时间
        //带权周转时间为该进程完成时间/运行时间

        System.out.println("\n：开始时间是： ");
        for (i = 0; i < process_number; i++) {
            System.out.print(start_time[i] + "\t");

        }

        System.out.println("\n等待时间是：");
        for (i = 0; i < process_number; i++) {
            System.out.print(wait_time[i] + "\t");
        }

        System.out.println("\n完成时间是：");
        for (i = 0; i < process_number; i++) {
            System.out.print(completion_time[i] + "\t");
        }

        System.out.println("\n周转时间是：");
        for (i = 0; i < process_number; i++) {
            System.out.print(turn_around_time[i] + "\t");
        }

        System.out.println("\n带权周转时间：");
        for (i = 0; i < process_number; i++) {
            System.out.print(turn_around_time_with_weight[i] + "\t");
        }

        for (i = 0; i < process_number; i++) {
            average_turn_around_time=average_turn_around_time+turn_around_time[i];
        }
        System.out.println("\n平均周转时间："+(average_turn_around_time/process_number));

        for (i = 0; i < process_number; i++) {
            average_turn_around_time_with_weight=average_turn_around_time_with_weight+turn_around_time_with_weight[i];
        }
        System.out.println("\n平均带权周转时间："+(average_turn_around_time_with_weight/process_number));

    }

    public static void main(String[] args) throws Exception {
        System.out.println("请输入进程数：");
        Awara_OS_FCFS cok = new Awara_OS_FCFS();
        BufferedReader buf = null;
        buf = new BufferedReader(new InputStreamReader(System.in));//获取输入数值
        String str1 = null;
        str1 = buf.readLine();//获取输入的进程数
        cok.process_number = (int) Double.parseDouble(str1);
        cok.arrival_time = new double[cok.process_number];
        cok.services_time = new double[cok.process_number];
        cok.completion_time = new double[cok.process_number ];
        cok.turn_around_time = new double[cok.process_number];
        cok.start_time = new double[cok.process_number];
        cok.wait_time = new double[cok.process_number];
        cok.turn_around_time_with_weight = new double[cok.process_number];
        //给对应属性初始化数组长度

        String str = null;
        String str2 = null;

        System.out.println("\n请输入各进程到达时间");
        for (i = 0; i < cok.process_number; i++) {
            str = buf.readLine();
            cok.arrival_time[i] = Double.parseDouble(str);
        }

        System.out.println("\n请输入各个进程服务时间");
        for (i = 0; i < cok.process_number; i++) {
            str2 = buf.readLine();
            cok.services_time[i] = Double.parseDouble(str2);

        }
        System.out.println("该进程数为" + cok.process_number);
        System.out.println("\n到达时间为");
        for (i = 0; i < cok.process_number; i++) {
            System.out.print(cok.arrival_time[i] + "\t");
        }
        System.out.println("\n服务时间为：");
        for (i = 0; i < cok.process_number; i++) {
            System.out.print(cok.services_time[i] + "\t");
        }
        cok.FCFS();

    }

}